﻿using Newtonsoft.Json.Linq;
using ServiceStack.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using ShoppingCart.WebApi.Models;
using ShoppingCart.WebApi.DataLayer;
using System.Diagnostics;
using System.Text;
using System.Web;
using Newtonsoft.Json;

namespace ShoppingCart.WebApi.Controllers
{
    
    public class CartController : ApiController
    {
        RedisRepository repository = new RedisRepository();

        private String GenerateErrorMessage(String message)
        {
            return "{\"Message\":\"" + message + "\"}";
        }

        // GET api/cart/5
        // To test: use browser. http://localhost:61563/api/cart/dXNlcjFAaG90bWFpbC5jb20=
        [HttpGet]
        public HttpResponseMessage Get(String encodedUserId)
        {
            HttpResponseMessage response;

            try
            {
                //change Base64 encoding to user id            
                //this will throw a FormatException if the encodedUserId is not a properly formatted Base64Encoded string, caught below
                var userId = Encoding.Default.GetString(Convert.FromBase64String(encodedUserId));
                var shoppingcart = repository.GetShoppingCart(userId);

                if (shoppingcart != null)
                {
                    response = Request.CreateResponse<ShoppingCartModel>(HttpStatusCode.OK, shoppingcart);
                }
                else
                {
                    response = Request.CreateErrorResponse(
                        HttpStatusCode.NotFound,
                        string.Format("User Id {0} not found.", userId));
                }

                return response;
            }
            //will occur when encodedUserId is not a proper Base64 Encoded string.
            catch (FormatException)
            {
                return Request.CreateErrorResponse(
                        HttpStatusCode.Unauthorized,
                        string.Format("UserId {0} is invalid.", encodedUserId)
                );
            }
            catch(Exception e)
            {
                return Request.CreateErrorResponse(
                        HttpStatusCode.InternalServerError,
                        string.Format(e.Message)
                );
            }
        }

        // POST api/cart
        // To test: use Fiddler;
        // send post to http://localhost:61563/api/cart 
        // using request body: {"userId" : "user1@hotmail.com",
        //                      "items" : [
        //                          {"prodId" : "5168bed10fdb8c0e7c671d32","prodName" : "NoSQL Distilled","prodDesc" : "A brief guide to the emerging world of polyglot persistence.","prodPrice" : 24.99,"quantity" : 1,"imageUrl": "/productimages/101.png",},
        //                          {"prodId" : "5168f7310fdb8c13e46a6c61","prodName" : "Seven Databases in Seven Weeks","prodDesc" : "A guide to modern databases and the NoSQL movement","prodPrice" : 26.99,"quantity" : 1,"imageUrl": "/productimages/102.png"}
        //                      ]}
        //
        [HttpPost]
        public HttpResponseMessage Post([FromBody]JObject json)
        {
            HttpResponseMessage response;

            try
            {
                if (json == null)
                    throw new ShoppingCartException("Wrong Input");

                var userId = (string)json.GetValue("userId");
                
                ShoppingCartModel shoppingCart = JsonConvert.DeserializeObject<ShoppingCartModel>(json.ToString());
                if (shoppingCart.userId == null || shoppingCart.items == null || shoppingCart.items.Count == 0)
                    throw new ShoppingCartException("Wrong Input");

                repository.AddShoppingCart(shoppingCart);

                response = Request.CreateResponse(HttpStatusCode.Created);
                response.Headers.Location = new Uri(
                    Request.RequestUri + "/" + 
                    Convert.ToBase64String(Encoding.Default.GetBytes(userId))
                );
            }
            catch (ShoppingCartException e)
            {
                Trace.WriteLine(e.ToString());
                response = Request.CreateErrorResponse(
                                HttpStatusCode.BadRequest, e.ToString());
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.ToString());
                response = Request.CreateErrorResponse(
                                HttpStatusCode.InternalServerError, e.ToString());
            }

            return response;
            
        }

        // DELETE api/cart/5
        // To test: use Fiddler. send delete to http://localhost:61563/api/cart/dXNlcjFAaG90bWFpbC5jb20=
        public HttpResponseMessage Delete(String encodedUserId)
        {
            try
            {
                //change Base64 encoding to user id
                String userId = Encoding.Default.GetString(Convert.FromBase64String(encodedUserId));

                repository.DeleteShoppingCart(userId);
                return Request.CreateResponse(HttpStatusCode.OK);
            }
            catch (ShoppingCartException e)
            {
                Trace.WriteLine(e.ToString());
                return Request.CreateErrorResponse(
                    HttpStatusCode.NotFound,
                    string.Format("User Id {0} not found.", encodedUserId));
            }
            //will occur when encodedUserId is not a proper Base64 Encoded string.
            catch (FormatException)
            {
                return Request.CreateErrorResponse(
                        HttpStatusCode.Unauthorized,
                        string.Format("UserId {0} is invalid.", encodedUserId)
                );
            }
            catch (Exception e)
            {
                Trace.WriteLine(e.ToString());
                return Request.CreateErrorResponse(
                    HttpStatusCode.InternalServerError,
                    e.ToString());
            }
        }
    }
}
